/*
  Boot loader command
    help
    boot arg0 arg1
    dn filename address(default : 0xc0000000)
    tftp filename address(default : 0xc0000000)
    flash dest_address source_address length
    bl_flash source_address length
    dump address length
    memset address value length
    jump address
    gpioset value
    gpiord
    ram_test start_address length(Mbytes)
    net_test
    script address
*/

# include "config.h"

#include "command.h"
#include "serial.h"
#include "time.h"
#include "types.h"
#include "util.h"
#include "tat.h"


/* display a prompt, or the standard prompt if prompt == NULL */
void DisplayPrompt(char *prompt)
{
	if(prompt == NULL) {
		if( verbose_level > 0 )
			printk("\nBlob> ");
	} else {
		if( verbose_level > 0 )
			printk("%s", prompt);
	}
}


/* more or less like SerialInputString(), but with echo and backspace  */
int GetCommand(char *command, int len, int timeout)
{
	u32 startTime, currentTime;
	char c;
	int i;
	int numRead;
	int maxRead = len - 1;

	startTime = TimerGetTime();

	for(numRead = 0, i = 0; numRead < maxRead;) {
		/* try to get a byte from the serial port */
		while(!SerialInputByte(&c)) {
			currentTime = TimerGetTime();

			/* check timeout value */
			if((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) {
				/* timeout */
				command[i++] = '\0';
				return(numRead);
			}
		}

		if((c == '\r') || (c == '\n')) {
			if(i==0){
				if( verbose_level > 0 )
					printk("\n");
				DisplayPrompt("\nEldr>");
				numRead = 0;
			} else {
				command[i++] = '\0';
				/* print newline */
				if( verbose_level > 0 )
					printk("\n");
				return(numRead);
			}
		} else
			if(c == '\b') { /* FIXME: is this backspace? */
				if(i > 0) {
					i--;
					numRead--;
					/* cursor one position back. */
				if( verbose_level > 0 )
					printk("\b \b");
				}
			} else {
				command[i++] = c;
				numRead++;

				/* print character */
				if( verbose_level > 0 )
					printk("%c", c);
			}
	}

	return(numRead);
}

/*
  Parse a file name from the input command
*/
int ParseFileName(u8* InputCommand, int* NextReadLocation, u8* FileName)
{
	int i=0;
	int StartLocation;

	while((InputCommand[i]==' ')||(InputCommand[i]=='\t')) i++; /* skips the preceeding blanks */
	StartLocation = i;
	while((InputCommand[i]!=' ')&&(InputCommand[i]!='\t')&&(InputCommand[i]!='\0')&&(InputCommand[i]!='\r')&&(InputCommand[i]!='\n')){
	FileName[i-StartLocation]=InputCommand[i];
	i++;
	}
	if((i==StartLocation)||(InputCommand[StartLocation]=='\0')) return 0; /* no filename */
		FileName[i-StartLocation]='\0';
	(*NextReadLocation) = i;

	return 1;
}

/*
  return -1 when there's error in the input
          0 when there's no input number
          1 when ok
*/
int ParseNumber(u8* InputCommand, int* NextReadLocation, u32* ReadValue)
{
	int i=0;
	u32 ValuePerDigit = 10;
	u32 Input = 0;
	int StartLocation;

	while((InputCommand[i]==' ')||(InputCommand[i]=='\t')) i++; /* skips the preceeding blanks */
	StartLocation = i;
	if(MyStrCmp(InputCommand+i, "0x", 2)){ /* hexa mode */
		ValuePerDigit = 0x10;
		i+=2;
	}

	while((InputCommand[i]!=' ')&&(InputCommand[i]!='\t')&&(InputCommand[i]!='\0')&&(InputCommand[i]!='\r')&&(InputCommand[i]!='\n')){
		if((InputCommand[i]>='0')&&(InputCommand[i]<='9')){ /* normal digit */
			Input*= ValuePerDigit;
			Input += (InputCommand[i]-'0');
		} else if((InputCommand[i]>='a')&&(InputCommand[i]<='f')){ /* hexadecimal */
			Input*= ValuePerDigit;
			Input += (InputCommand[i]-'a'+10);
		} else if((InputCommand[i]>='A')&&(InputCommand[i]<='F')){ /* hexadecimal */
			Input*= ValuePerDigit;
			Input += (InputCommand[i]-'A'+10);
		} else {
			printk("Error : unrecognized number in %s \n", InputCommand);
			return -1;
		}
		i++;
	}

	if((i==StartLocation)||(InputCommand[StartLocation]=='\0')) return 0; /* no number */
	(*NextReadLocation) = i;
	(*ReadValue) = Input;
	return 1;
}
